home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / ViePratique / ArchiFacile / ArchiFacileSetup.exe / {app} / nw.pak / Unnamed File 001037.txt < prev    next >
Text File  |  2014-10-14  |  32KB  |  1,065 lines

  1. (function() {
  2.     /*
  3.  * Copyright (C) 2012 Google Inc. All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions are
  7.  * met:
  8.  *
  9.  *     * Redistributions of source code must retain the above copyright
  10.  * notice, this list of conditions and the following disclaimer.
  11.  *     * Redistributions in binary form must reproduce the above
  12.  * copyright notice, this list of conditions and the following disclaimer
  13.  * in the documentation and/or other materials provided with the
  14.  * distribution.
  15.  *     * Neither the name of Google Inc. nor the names of its
  16.  * contributors may be used to endorse or promote products derived from
  17.  * this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  */
  31.  
  32. function defineCommonExtensionSymbols(apiPrivate)
  33. {
  34.     if (!apiPrivate.audits)
  35.         apiPrivate.audits = {};
  36.     apiPrivate.audits.Severity = {
  37.         Info: "info",
  38.         Warning: "warning",
  39.         Severe: "severe"
  40.     };
  41.  
  42.     if (!apiPrivate.console)
  43.         apiPrivate.console = {};
  44.     apiPrivate.console.Severity = {
  45.         Debug: "debug",
  46.         Log: "log",
  47.         Warning: "warning",
  48.         Error: "error"
  49.     };
  50.  
  51.     if (!apiPrivate.panels)
  52.         apiPrivate.panels = {};
  53.     apiPrivate.panels.SearchAction = {
  54.         CancelSearch: "cancelSearch",
  55.         PerformSearch: "performSearch",
  56.         NextSearchResult: "nextSearchResult",
  57.         PreviousSearchResult: "previousSearchResult"
  58.     };
  59.  
  60.     apiPrivate.Events = {
  61.         AuditStarted: "audit-started-",
  62.         ButtonClicked: "button-clicked-",
  63.         ConsoleMessageAdded: "console-message-added",
  64.         PanelObjectSelected: "panel-objectSelected-",
  65.         NetworkRequestFinished: "network-request-finished",
  66.         OpenResource: "open-resource",
  67.         PanelSearch: "panel-search-",
  68.         ResourceAdded: "resource-added",
  69.         ResourceContentCommitted: "resource-content-committed",
  70.         TimelineEventRecorded: "timeline-event-recorded",
  71.         ViewShown: "view-shown-",
  72.         ViewHidden: "view-hidden-"
  73.     };
  74.  
  75.     apiPrivate.Commands = {
  76.         AddAuditCategory: "addAuditCategory",
  77.         AddAuditResult: "addAuditResult",
  78.         AddConsoleMessage: "addConsoleMessage",
  79.         AddRequestHeaders: "addRequestHeaders",
  80.         ApplyStyleSheet: "applyStyleSheet",
  81.         CreatePanel: "createPanel",
  82.         CreateSidebarPane: "createSidebarPane",
  83.         CreateStatusBarButton: "createStatusBarButton",
  84.         EvaluateOnInspectedPage: "evaluateOnInspectedPage",
  85.         ForwardKeyboardEvent: "_forwardKeyboardEvent",
  86.         GetConsoleMessages: "getConsoleMessages",
  87.         GetHAR: "getHAR",
  88.         GetPageResources: "getPageResources",
  89.         GetRequestContent: "getRequestContent",
  90.         GetResourceContent: "getResourceContent",
  91.         InspectedURLChanged: "inspectedURLChanged",
  92.         OpenResource: "openResource",
  93.         Reload: "Reload",
  94.         Subscribe: "subscribe",
  95.         SetOpenResourceHandler: "setOpenResourceHandler",
  96.         SetResourceContent: "setResourceContent",
  97.         SetSidebarContent: "setSidebarContent",
  98.         SetSidebarHeight: "setSidebarHeight",
  99.         SetSidebarPage: "setSidebarPage",
  100.         ShowPanel: "showPanel",
  101.         StopAuditCategoryRun: "stopAuditCategoryRun",
  102.         Unsubscribe: "unsubscribe",
  103.         UpdateAuditProgress: "updateAuditProgress",
  104.         UpdateButton: "updateButton"
  105.     };
  106. }
  107.  
  108. /**
  109.  * @param {number} injectedScriptId
  110.  * @return {!Object}
  111.  */
  112. function injectedExtensionAPI(injectedScriptId)
  113. {
  114.  
  115. var apiPrivate = {};
  116.  
  117. defineCommonExtensionSymbols(apiPrivate);
  118.  
  119. var commands = apiPrivate.Commands;
  120. var events = apiPrivate.Events;
  121. var userAction = false;
  122.  
  123. // Here and below, all constructors are private to API implementation.
  124. // For a public type Foo, if internal fields are present, these are on
  125. // a private FooImpl type, an instance of FooImpl is used in a closure
  126. // by Foo consutrctor to re-bind publicly exported members to an instance
  127. // of Foo.
  128.  
  129. /**
  130.  * @constructor
  131.  */
  132. function EventSinkImpl(type, customDispatch)
  133. {
  134.     this._type = type;
  135.     this._listeners = [];
  136.     this._customDispatch = customDispatch;
  137. }
  138.  
  139. EventSinkImpl.prototype = {
  140.     addListener: function(callback)
  141.     {
  142.         if (typeof callback !== "function")
  143.             throw "addListener: callback is not a function";
  144.         if (this._listeners.length === 0)
  145.             extensionServer.sendRequest({ command: commands.Subscribe, type: this._type });
  146.         this._listeners.push(callback);
  147.         extensionServer.registerHandler("notify-" + this._type, this._dispatch.bind(this));
  148.     },
  149.  
  150.     removeListener: function(callback)
  151.     {
  152.         var listeners = this._listeners;
  153.  
  154.         for (var i = 0; i < listeners.length; ++i) {
  155.             if (listeners[i] === callback) {
  156.                 listeners.splice(i, 1);
  157.                 break;
  158.             }
  159.         }
  160.         if (this._listeners.length === 0)
  161.             extensionServer.sendRequest({ command: commands.Unsubscribe, type: this._type });
  162.     },
  163.  
  164.     /**
  165.      * @param {...} vararg
  166.      */
  167.     _fire: function(vararg)
  168.     {
  169.         var listeners = this._listeners.slice();
  170.         for (var i = 0; i < listeners.length; ++i)
  171.             listeners[i].apply(null, arguments);
  172.     },
  173.  
  174.     _dispatch: function(request)
  175.     {
  176.          if (this._customDispatch)
  177.              this._customDispatch.call(this, request);
  178.          else
  179.              this._fire.apply(this, request.arguments);
  180.     }
  181. }
  182.  
  183. /**
  184.  * @constructor
  185.  */
  186. function InspectorExtensionAPI()
  187. {
  188.     this.audits = new Audits();
  189.     this.inspectedWindow = new InspectedWindow();
  190.     this.panels = new Panels();
  191.     this.network = new Network();
  192.     defineDeprecatedProperty(this, "webInspector", "resources", "network");
  193.     this.timeline = new Timeline();
  194.     this.console = new ConsoleAPI();
  195. }
  196.  
  197. /**
  198.  * @constructor
  199.  */
  200. function ConsoleAPI()
  201. {
  202.     this.onMessageAdded = new EventSink(events.ConsoleMessageAdded);
  203. }
  204.  
  205. ConsoleAPI.prototype = {
  206.     getMessages: function(callback)
  207.     {
  208.         extensionServer.sendRequest({ command: commands.GetConsoleMessages }, callback);
  209.     },
  210.  
  211.     addMessage: function(severity, text, url, line)
  212.     {
  213.         extensionServer.sendRequest({ command: commands.AddConsoleMessage, severity: severity, text: text, url: url, line: line });
  214.     },
  215.  
  216.     get Severity()
  217.     {
  218.         return apiPrivate.console.Severity;
  219.     }
  220. }
  221.  
  222. /**
  223.  * @constructor
  224.  */
  225. function Network()
  226. {
  227.     /**
  228.      * @this {EventSinkImpl}
  229.      */
  230.     function dispatchRequestEvent(message)
  231.     {
  232.         var request = message.arguments[1];
  233.         request.__proto__ = new Request(message.arguments[0]);
  234.         this._fire(request);
  235.     }
  236.     this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispatchRequestEvent);
  237.     defineDeprecatedProperty(this, "network", "onFinished", "onRequestFinished");
  238.     this.onNavigated = new EventSink(events.InspectedURLChanged);
  239. }
  240.  
  241. Network.prototype = {
  242.     getHAR: function(callback)
  243.     {
  244.         function callbackWrapper(result)
  245.         {
  246.             var entries = (result && result.entries) || [];
  247.             for (var i = 0; i < entries.length; ++i) {
  248.                 entries[i].__proto__ = new Request(entries[i]._requestId);
  249.                 delete entries[i]._requestId;
  250.             }
  251.             callback(result);
  252.         }
  253.         extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper);
  254.     },
  255.  
  256.     addRequestHeaders: function(headers)
  257.     {
  258.         extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname });
  259.     }
  260. }
  261.  
  262. /**
  263.  * @constructor
  264.  */
  265. function RequestImpl(id)
  266. {
  267.     this._id = id;
  268. }
  269.  
  270. RequestImpl.prototype = {
  271.     getContent: function(callback)
  272.     {
  273.         function callbackWrapper(response)
  274.         {
  275.             callback(response.content, response.encoding);
  276.         }
  277.         extensionServer.sendRequest({ command: commands.GetRequestContent, id: this._id }, callback && callbackWrapper);
  278.     }
  279. }
  280.  
  281. /**
  282.  * @constructor
  283.  */
  284. function Panels()
  285. {
  286.     var panels = {
  287.         elements: new ElementsPanel(),
  288.         sources: new SourcesPanel(),
  289.     };
  290.  
  291.     function panelGetter(name)
  292.     {
  293.         return panels[name];
  294.     }
  295.     for (var panel in panels)
  296.         this.__defineGetter__(panel, panelGetter.bind(null, panel));
  297.     this.applyStyleSheet = function(styleSheet) { extensionServer.sendRequest({ command: commands.ApplyStyleSheet, styleSheet: styleSheet }); };
  298. }
  299.  
  300. Panels.prototype = {
  301.     create: function(title, icon, page, callback)
  302.     {
  303.         var id = "extension-panel-" + extensionServer.nextObjectId();
  304.         var request = {
  305.             command: commands.CreatePanel,
  306.             id: id,
  307.             title: title,
  308.             icon: icon,
  309.             page: page
  310.         };
  311.         extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id)));
  312.     },
  313.  
  314.     setOpenResourceHandler: function(callback)
  315.     {
  316.         var hadHandler = extensionServer.hasHandler(events.OpenResource);
  317.  
  318.         function callbackWrapper(message)
  319.         {
  320.             // Allow the panel to show itself when handling the event.
  321.             userAction = true;
  322.             try {
  323.                 callback.call(null, new Resource(message.resource), message.lineNumber);
  324.             } finally {
  325.                 userAction = false;
  326.             }
  327.         }
  328.  
  329.         if (!callback)
  330.             extensionServer.unregisterHandler(events.OpenResource);
  331.         else
  332.             extensionServer.registerHandler(events.OpenResource, callbackWrapper);
  333.  
  334.         // Only send command if we either removed an existing handler or added handler and had none before.
  335.         if (hadHandler === !callback)
  336.             extensionServer.sendRequest({ command: commands.SetOpenResourceHandler, "handlerPresent": !!callback });
  337.     },
  338.  
  339.     openResource: function(url, lineNumber, callback)
  340.     {
  341.         extensionServer.sendRequest({ command: commands.OpenResource, "url": url, "lineNumber": lineNumber }, callback);
  342.     },
  343.  
  344.     get SearchAction()
  345.     {
  346.         return apiPrivate.panels.SearchAction;
  347.     }
  348. }
  349.  
  350. /**
  351.  * @constructor
  352.  */
  353. function ExtensionViewImpl(id)
  354. {
  355.     this._id = id;
  356.  
  357.     /**
  358.      * @this {EventSinkImpl}
  359.      */
  360.     function dispatchShowEvent(message)
  361.     {
  362.         var frameIndex = message.arguments[0];
  363.         if (typeof frameIndex === "number")
  364.             this._fire(window.parent.frames[frameIndex]);
  365.         else
  366.             this._fire();
  367.     }
  368.  
  369.     if (id) {
  370.         this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent);
  371.         this.onHidden = new EventSink(events.ViewHidden + id);
  372.     }
  373. }
  374.  
  375. /**
  376.  * @constructor
  377.  * @extends {ExtensionViewImpl}
  378.  * @param {string} hostPanelName
  379.  */
  380. function PanelWithSidebarImpl(hostPanelName)
  381. {
  382.     ExtensionViewImpl.call(this, null);
  383.     this._hostPanelName = hostPanelName;
  384.     this.onSelectionChanged = new EventSink(events.PanelObjectSelected + hostPanelName);
  385. }
  386.  
  387. PanelWithSidebarImpl.prototype = {
  388.     createSidebarPane: function(title, callback)
  389.     {
  390.         var id = "extension-sidebar-" + extensionServer.nextObjectId();
  391.         var request = {
  392.             command: commands.CreateSidebarPane,
  393.             panel: this._hostPanelName,
  394.             id: id,
  395.             title: title
  396.         };
  397.         function callbackWrapper()
  398.         {
  399.             callback(new ExtensionSidebarPane(id));
  400.         }
  401.         extensionServer.sendRequest(request, callback && callbackWrapper);
  402.     },
  403.  
  404.     __proto__: ExtensionViewImpl.prototype
  405. }
  406.  
  407. function declareInterfaceClass(implConstructor)
  408. {
  409.     return function()
  410.     {
  411.         var impl = { __proto__: implConstructor.prototype };
  412.         implConstructor.apply(impl, arguments);
  413.         populateInterfaceClass(this, impl);
  414.     }
  415. }
  416.  
  417. function defineDeprecatedProperty(object, className, oldName, newName)
  418. {
  419.     var warningGiven = false;
  420.     function getter()
  421.     {
  422.         if (!warningGiven) {
  423.             console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead");
  424.             warningGiven = true;
  425.         }
  426.         return object[newName];
  427.     }
  428.     object.__defineGetter__(oldName, getter);
  429. }
  430.  
  431. function extractCallbackArgument(args)
  432. {
  433.     var lastArgument = args[args.length - 1];
  434.     return typeof lastArgument === "function" ? lastArgument : undefined;
  435. }
  436.  
  437. var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
  438. var AuditResult = declareInterfaceClass(AuditResultImpl);
  439. var Button = declareInterfaceClass(ButtonImpl);
  440. var EventSink = declareInterfaceClass(EventSinkImpl);
  441. var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
  442. var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
  443. var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
  444. var Request = declareInterfaceClass(RequestImpl);
  445. var Resource = declareInterfaceClass(ResourceImpl);
  446. var Timeline = declareInterfaceClass(TimelineImpl);
  447.  
  448. /**
  449.  * @constructor
  450.  * @extends {PanelWithSidebar}
  451.  */
  452. function ElementsPanel()
  453. {
  454.     PanelWithSidebar.call(this, "elements");
  455. }
  456.  
  457. ElementsPanel.prototype = {
  458.     __proto__: PanelWithSidebar.prototype
  459. }
  460.  
  461. /**
  462.  * @constructor
  463.  * @extends {PanelWithSidebar}
  464.  */
  465. function SourcesPanel()
  466. {
  467.     PanelWithSidebar.call(this, "sources");
  468. }
  469.  
  470. SourcesPanel.prototype = {
  471.     __proto__: PanelWithSidebar.prototype
  472. }
  473.  
  474. /**
  475.  * @constructor
  476.  * @extends {ExtensionViewImpl}
  477.  */
  478. function ExtensionPanelImpl(id)
  479. {
  480.     ExtensionViewImpl.call(this, id);
  481.     this.onSearch = new EventSink(events.PanelSearch + id);
  482. }
  483.  
  484. ExtensionPanelImpl.prototype = {
  485.     /**
  486.      * @return {!Object}
  487.      */
  488.     createStatusBarButton: function(iconPath, tooltipText, disabled)
  489.     {
  490.         var id = "button-" + extensionServer.nextObjectId();
  491.         var request = {
  492.             command: commands.CreateStatusBarButton,
  493.             panel: this._id,
  494.             id: id,
  495.             icon: iconPath,
  496.             tooltip: tooltipText,
  497.             disabled: !!disabled
  498.         };
  499.         extensionServer.sendRequest(request);
  500.         return new Button(id);
  501.     },
  502.  
  503.     show: function()
  504.     {
  505.         if (!userAction)
  506.             return;
  507.  
  508.         var request = {
  509.             command: commands.ShowPanel,
  510.             id: this._id
  511.         };
  512.         extensionServer.sendRequest(request);
  513.     },
  514.  
  515.     __proto__: ExtensionViewImpl.prototype
  516. }
  517.  
  518. /**
  519.  * @constructor
  520.  * @extends {ExtensionViewImpl}
  521.  */
  522. function ExtensionSidebarPaneImpl(id)
  523. {
  524.     ExtensionViewImpl.call(this, id);
  525. }
  526.  
  527. ExtensionSidebarPaneImpl.prototype = {
  528.     setHeight: function(height)
  529.     {
  530.         extensionServer.sendRequest({ command: commands.SetSidebarHeight, id: this._id, height: height });
  531.     },
  532.  
  533.     setExpression: function(expression, rootTitle, evaluateOptions)
  534.     {
  535.         var request = {
  536.             command: commands.SetSidebarContent,
  537.             id: this._id,
  538.             expression: expression,
  539.             rootTitle: rootTitle,
  540.             evaluateOnPage: true,
  541.         };
  542.         if (typeof evaluateOptions === "object")
  543.             request.evaluateOptions = evaluateOptions;
  544.         extensionServer.sendRequest(request, extractCallbackArgument(arguments));
  545.     },
  546.  
  547.     setObject: function(jsonObject, rootTitle, callback)
  548.     {
  549.         extensionServer.sendRequest({ command: commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle }, callback);
  550.     },
  551.  
  552.     setPage: function(page)
  553.     {
  554.         extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this._id, page: page });
  555.     },
  556.  
  557.     __proto__: ExtensionViewImpl.prototype
  558. }
  559.  
  560. /**
  561.  * @constructor
  562.  */
  563. function ButtonImpl(id)
  564. {
  565.     this._id = id;
  566.     this.onClicked = new EventSink(events.ButtonClicked + id);
  567. }
  568.  
  569. ButtonImpl.prototype = {
  570.     update: function(iconPath, tooltipText, disabled)
  571.     {
  572.         var request = {
  573.             command: commands.UpdateButton,
  574.             id: this._id,
  575.             icon: iconPath,
  576.             tooltip: tooltipText,
  577.             disabled: !!disabled
  578.         };
  579.         extensionServer.sendRequest(request);
  580.     }
  581. };
  582.  
  583. /**
  584.  * @constructor
  585.  */
  586. function Audits()
  587. {
  588. }
  589.  
  590. Audits.prototype = {
  591.     /**
  592.      * @return {!AuditCategory}
  593.      */
  594.     addCategory: function(displayName, resultCount)
  595.     {
  596.         var id = "extension-audit-category-" + extensionServer.nextObjectId();
  597.         if (typeof resultCount !== "undefined")
  598.             console.warn("Passing resultCount to audits.addCategory() is deprecated. Use AuditResult.updateProgress() instead.");
  599.         extensionServer.sendRequest({ command: commands.AddAuditCategory, id: id, displayName: displayName, resultCount: resultCount });
  600.         return new AuditCategory(id);
  601.     }
  602. }
  603.  
  604. /**
  605.  * @constructor
  606.  */
  607. function AuditCategoryImpl(id)
  608. {
  609.     /**
  610.      * @this {EventSinkImpl}
  611.      */
  612.     function dispatchAuditEvent(request)
  613.     {
  614.         var auditResult = new AuditResult(request.arguments[0]);
  615.         try {
  616.             this._fire(auditResult);
  617.         } catch (e) {
  618.             console.error("Uncaught exception in extension audit event handler: " + e);
  619.             auditResult.done();
  620.         }
  621.     }
  622.     this._id = id;
  623.     this.onAuditStarted = new EventSink(events.AuditStarted + id, dispatchAuditEvent);
  624. }
  625.  
  626. /**
  627.  * @constructor
  628.  */
  629. function AuditResultImpl(id)
  630. {
  631.     this._id = id;
  632.  
  633.     this.createURL = this._nodeFactory.bind(this, "url");
  634.     this.createSnippet = this._nodeFactory.bind(this, "snippet");
  635.     this.createText = this._nodeFactory.bind(this, "text");
  636.     this.createObject = this._nodeFactory.bind(this, "object");
  637.     this.createNode = this._nodeFactory.bind(this, "node");
  638. }
  639.  
  640. AuditResultImpl.prototype = {
  641.     addResult: function(displayName, description, severity, details)
  642.     {
  643.         // shorthand for specifying details directly in addResult().
  644.         if (details && !(details instanceof AuditResultNode))
  645.             details = new AuditResultNode(details instanceof Array ? details : [details]);
  646.  
  647.         var request = {
  648.             command: commands.AddAuditResult,
  649.             resultId: this._id,
  650.             displayName: displayName,
  651.             description: description,
  652.             severity: severity,
  653.             details: details
  654.         };
  655.         extensionServer.sendRequest(request);
  656.     },
  657.  
  658.     /**
  659.      * @return {!Object}
  660.      */
  661.     createResult: function()
  662.     {
  663.         return new AuditResultNode(Array.prototype.slice.call(arguments));
  664.     },
  665.  
  666.     updateProgress: function(worked, totalWork)
  667.     {
  668.         extensionServer.sendRequest({ command: commands.UpdateAuditProgress, resultId: this._id, progress: worked / totalWork });
  669.     },
  670.  
  671.     done: function()
  672.     {
  673.         extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, resultId: this._id });
  674.     },
  675.  
  676.     /**
  677.      * @type {!Object.<string, string>}
  678.      */
  679.     get Severity()
  680.     {
  681.         return apiPrivate.audits.Severity;
  682.     },
  683.  
  684.     /**
  685.      * @return {!{type: string, arguments: !Array.<string|number>}}
  686.      */
  687.     createResourceLink: function(url, lineNumber)
  688.     {
  689.         return {
  690.             type: "resourceLink",
  691.             arguments: [url, lineNumber && lineNumber - 1]
  692.         };
  693.     },
  694.  
  695.     /**
  696.      * @return {!{type: string, arguments: !Array.<string|number>}}
  697.      */
  698.     _nodeFactory: function(type)
  699.     {
  700.         return {
  701.             type: type,
  702.             arguments: Array.prototype.slice.call(arguments, 1)
  703.         };
  704.     }
  705. }
  706.  
  707. /**
  708.  * @constructor
  709.  */
  710. function AuditResultNode(contents)
  711. {
  712.     this.contents = contents;
  713.     this.children = [];
  714.     this.expanded = false;
  715. }
  716.  
  717. AuditResultNode.prototype = {
  718.     /**
  719.      * @return {!Object}
  720.      */
  721.     addChild: function()
  722.     {
  723.         var node = new AuditResultNode(Array.prototype.slice.call(arguments));
  724.         this.children.push(node);
  725.         return node;
  726.     }
  727. };
  728.  
  729. /**
  730.  * @constructor
  731.  */
  732. function InspectedWindow()
  733. {
  734.     /**
  735.      * @this {EventSinkImpl}
  736.      */
  737.     function dispatchResourceEvent(message)
  738.     {
  739.         this._fire(new Resource(message.arguments[0]));
  740.     }
  741.  
  742.     /**
  743.      * @this {EventSinkImpl}
  744.      */
  745.     function dispatchResourceContentEvent(message)
  746.     {
  747.         this._fire(new Resource(message.arguments[0]), message.arguments[1]);
  748.     }
  749.  
  750.     this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent);
  751.     this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent);
  752. }
  753.  
  754. InspectedWindow.prototype = {
  755.     reload: function(optionsOrUserAgent)
  756.     {
  757.         var options = null;
  758.         if (typeof optionsOrUserAgent === "object")
  759.             options = optionsOrUserAgent;
  760.         else if (typeof optionsOrUserAgent === "string") {
  761.             options = { userAgent: optionsOrUserAgent };
  762.             console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. " +
  763.                          "Use inspectedWindow.reload({ userAgent: value}) instead.");
  764.         }
  765.         extensionServer.sendRequest({ command: commands.Reload, options: options });
  766.     },
  767.  
  768.     /**
  769.      * @return {?Object}
  770.      */
  771.     eval: function(expression, evaluateOptions)
  772.     {
  773.         var callback = extractCallbackArgument(arguments);
  774.         function callbackWrapper(result)
  775.         {
  776.             if (result.isError || result.isException)
  777.                 callback(undefined, result);
  778.             else
  779.                 callback(result.value);
  780.         }
  781.         var request = {
  782.             command: commands.EvaluateOnInspectedPage,
  783.             expression: expression
  784.         };
  785.         if (typeof evaluateOptions === "object")
  786.             request.evaluateOptions = evaluateOptions;
  787.         extensionServer.sendRequest(request, callback && callbackWrapper);
  788.         return null;
  789.     },
  790.  
  791.     getResources: function(callback)
  792.     {
  793.         function wrapResource(resourceData)
  794.         {
  795.             return new Resource(resourceData);
  796.         }
  797.         function callbackWrapper(resources)
  798.         {
  799.             callback(resources.map(wrapResource));
  800.         }
  801.         extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper);
  802.     }
  803. }
  804.  
  805. /**
  806.  * @constructor
  807.  */
  808. function ResourceImpl(resourceData)
  809. {
  810.     this._url = resourceData.url
  811.     this._type = resourceData.type;
  812. }
  813.  
  814. ResourceImpl.prototype = {
  815.     get url()
  816.     {
  817.         return this._url;
  818.     },
  819.  
  820.     get type()
  821.     {
  822.         return this._type;
  823.     },
  824.  
  825.     getContent: function(callback)
  826.     {
  827.         function callbackWrapper(response)
  828.         {
  829.             callback(response.content, response.encoding);
  830.         }
  831.  
  832.         extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper);
  833.     },
  834.  
  835.     setContent: function(content, commit, callback)
  836.     {
  837.         extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
  838.     }
  839. }
  840.  
  841. /**
  842.  * @constructor
  843.  */
  844. function TimelineImpl()
  845. {
  846.     this.onEventRecorded = new EventSink(events.TimelineEventRecorded);
  847. }
  848.  
  849. var keyboardEventRequestQueue = [];
  850. var forwardTimer = null;
  851.  
  852. function forwardKeyboardEvent(event)
  853. {
  854.     const Esc = "U+001B";
  855.     // We only care about global hotkeys, not about random text
  856.     if (!event.ctrlKey && !event.altKey && !event.metaKey && !/^F\d+$/.test(event.keyIdentifier) && event.keyIdentifier !== Esc)
  857.         return;
  858.     var requestPayload = {
  859.         eventType: event.type,
  860.         ctrlKey: event.ctrlKey,
  861.         altKey: event.altKey,
  862.         metaKey: event.metaKey,
  863.         keyIdentifier: event.keyIdentifier,
  864.         location: event.location,
  865.         keyCode: event.keyCode
  866.     };
  867.     keyboardEventRequestQueue.push(requestPayload);
  868.     if (!forwardTimer)
  869.         forwardTimer = setTimeout(forwardEventQueue, 0);
  870. }
  871.  
  872. function forwardEventQueue()
  873. {
  874.     forwardTimer = null;
  875.     var request = {
  876.         command: commands.ForwardKeyboardEvent,
  877.         entries: keyboardEventRequestQueue
  878.     };
  879.     extensionServer.sendRequest(request);
  880.     keyboardEventRequestQueue = [];
  881. }
  882.  
  883. document.addEventListener("keydown", forwardKeyboardEvent, false);
  884. document.addEventListener("keypress", forwardKeyboardEvent, false);
  885.  
  886. /**
  887.  * @constructor
  888.  */
  889. function ExtensionServerClient()
  890. {
  891.     this._callbacks = {};
  892.     this._handlers = {};
  893.     this._lastRequestId = 0;
  894.     this._lastObjectId = 0;
  895.  
  896.     this.registerHandler("callback", this._onCallback.bind(this));
  897.  
  898.     var channel = new MessageChannel();
  899.     this._port = channel.port1;
  900.     this._port.addEventListener("message", this._onMessage.bind(this), false);
  901.     this._port.start();
  902.  
  903.     window.parent.postMessage("registerExtension", [ channel.port2 ], "*");
  904. }
  905.  
  906. ExtensionServerClient.prototype = {
  907.     /**
  908.      * @param {function()=} callback
  909.      */
  910.     sendRequest: function(message, callback)
  911.     {
  912.         if (typeof callback === "function")
  913.             message.requestId = this._registerCallback(callback);
  914.         this._port.postMessage(message);
  915.     },
  916.  
  917.     /**
  918.      * @return {boolean}
  919.      */
  920.     hasHandler: function(command)
  921.     {
  922.         return !!this._handlers[command];
  923.     },
  924.  
  925.     registerHandler: function(command, handler)
  926.     {
  927.         this._handlers[command] = handler;
  928.     },
  929.  
  930.     unregisterHandler: function(command)
  931.     {
  932.         delete this._handlers[command];
  933.     },
  934.  
  935.     /**
  936.      * @return {string}
  937.      */
  938.     nextObjectId: function()
  939.     {
  940.         return injectedScriptId + "_" + ++this._lastObjectId;
  941.     },
  942.  
  943.     _registerCallback: function(callback)
  944.     {
  945.         var id = ++this._lastRequestId;
  946.         this._callbacks[id] = callback;
  947.         return id;
  948.     },
  949.  
  950.     _onCallback: function(request)
  951.     {
  952.         if (request.requestId in this._callbacks) {
  953.             var callback = this._callbacks[request.requestId];
  954.             delete this._callbacks[request.requestId];
  955.             callback(request.result);
  956.         }
  957.     },
  958.  
  959.     _onMessage: function(event)
  960.     {
  961.         var request = event.data;
  962.         var handler = this._handlers[request.command];
  963.         if (handler)
  964.             handler.call(this, request);
  965.     }
  966. }
  967.  
  968. function populateInterfaceClass(interface, implementation)
  969. {
  970.     for (var member in implementation) {
  971.         if (member.charAt(0) === "_")
  972.             continue;
  973.         var descriptor = null;
  974.         // Traverse prototype chain until we find the owner.
  975.         for (var owner = implementation; owner && !descriptor; owner = owner.__proto__)
  976.             descriptor = Object.getOwnPropertyDescriptor(owner, member);
  977.         if (!descriptor)
  978.             continue;
  979.         if (typeof descriptor.value === "function")
  980.             interface[member] = descriptor.value.bind(implementation);
  981.         else if (typeof descriptor.get === "function")
  982.             interface.__defineGetter__(member, descriptor.get.bind(implementation));
  983.         else
  984.             Object.defineProperty(interface, member, descriptor);
  985.     }
  986. }
  987.  
  988. // extensionServer is a closure variable defined by the glue below -- make sure we fail if it's not there.
  989. if (!extensionServer)
  990.     extensionServer = new ExtensionServerClient();
  991.  
  992. return new InspectorExtensionAPI();
  993. }
  994.  
  995. /**
  996.  * @suppress {checkVars, checkTypes}
  997.  */
  998. function platformExtensionAPI(coreAPI)
  999. {
  1000.     function getTabId()
  1001.     {
  1002.         return tabId;
  1003.     }
  1004.     chrome = window.chrome || {};
  1005.     // Override chrome.devtools as a workaround for a error-throwing getter being exposed
  1006.     // in extension pages loaded into a non-extension process (only happens for remote client
  1007.     // extensions)
  1008.     var devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, "devtools");
  1009.     if (!devtools_descriptor || devtools_descriptor.get)
  1010.         Object.defineProperty(chrome, "devtools", { value: {}, enumerable: true });
  1011.     // Only expose tabId on chrome.devtools.inspectedWindow, not webInspector.inspectedWindow.
  1012.     chrome.devtools.inspectedWindow = {};
  1013.     chrome.devtools.inspectedWindow.__defineGetter__("tabId", getTabId);
  1014.     chrome.devtools.inspectedWindow.__proto__ = coreAPI.inspectedWindow;
  1015.     chrome.devtools.network = coreAPI.network;
  1016.     chrome.devtools.panels = coreAPI.panels;
  1017.  
  1018.     // default to expose experimental APIs for now.
  1019.     if (extensionInfo.exposeExperimentalAPIs !== false) {
  1020.         chrome.experimental = chrome.experimental || {};
  1021.         chrome.experimental.devtools = chrome.experimental.devtools || {};
  1022.  
  1023.         var properties = Object.getOwnPropertyNames(coreAPI);
  1024.         for (var i = 0; i < properties.length; ++i) {
  1025.             var descriptor = Object.getOwnPropertyDescriptor(coreAPI, properties[i]);
  1026.             Object.defineProperty(chrome.experimental.devtools, properties[i], descriptor);
  1027.         }
  1028.         chrome.experimental.devtools.inspectedWindow = chrome.devtools.inspectedWindow;
  1029.     }
  1030.     if (extensionInfo.exposeWebInspectorNamespace)
  1031.         window.webInspector = coreAPI;
  1032. }
  1033.  
  1034. /**
  1035.  * @param {!ExtensionDescriptor} extensionInfo
  1036.  * @return {string}
  1037.  */
  1038. function buildPlatformExtensionAPI(extensionInfo)
  1039. {
  1040.     return "var extensionInfo = " + JSON.stringify(extensionInfo) + ";" +
  1041.        "var tabId = " + WebInspector._inspectedTabId + ";" +
  1042.        platformExtensionAPI.toString();
  1043. }
  1044.  
  1045. /**
  1046.  * @param {!ExtensionDescriptor} extensionInfo
  1047.  * @return {string}
  1048.  */
  1049. function buildExtensionAPIInjectedScript(extensionInfo)
  1050. {
  1051.     return "(function(injectedScriptId){ " +
  1052.         "var extensionServer;" +
  1053.         defineCommonExtensionSymbols.toString() + ";" +
  1054.         injectedExtensionAPI.toString() + ";" +
  1055.         buildPlatformExtensionAPI(extensionInfo) + ";" +
  1056.         "platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" +
  1057.         "return {};" +
  1058.         "})";
  1059. }
  1060.  
  1061.         var tabId;
  1062.         var extensionInfo = {};
  1063.         var extensionServer;
  1064.         platformExtensionAPI(injectedExtensionAPI("remote-" + window.parent.frames.length));
  1065.     })();